/*
 *  Blazon: A user datagram protocol re-braodcasting daemon.
 *  tools.h: Header file for tools.c
 *
 *  Copyright 2012 Blazon development team
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  Code derived from ratbox-services.
 *
 *  Copyright (C) 2003-2007 Lee Hardy <leeh@leeh.co.uk>
 *  Copyright (C) 2003-2012 ircd-ratbox development team
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *
 *  1.Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  2.Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  3.The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 *  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 *  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 *  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef INCLUDED_tools_h
#define INCLUDED_tools_h

#define STR_BUFSIZE	256

#define EmptyString(x) ((x == NULL) || (*(x) == '\0'))

#define my_malloc(x) (my_calloc(1, x))

extern void *my_calloc(size_t, size_t);
extern void *my_realloc(void *, size_t);
extern void my_free(void *);
extern char *my_strndup(const char *, size_t);
char *my_strdup(const char *);


extern const char *get_duration(time_t seconds);


typedef struct _dlink_node dlink_node;
typedef struct _dlink_list dlink_list;

struct _dlink_node
{
	void *data;
	dlink_node *prev;
	dlink_node *next;

};

struct _dlink_list
{
	dlink_node *head;
	dlink_node *tail;
	unsigned long length;
};

#define DLINK_EMPTY { NULL, NULL, 0 }

extern dlink_node *make_dlink_node(void);
extern void free_dlink_node(dlink_node *lp);

extern void dlink_move_node(dlink_node * m, dlink_list * oldlist, dlink_list * newlist);
extern void dlink_add(void *data, dlink_node * m, dlink_list * list);
extern void dlink_add_tail(void *data, dlink_node * m, dlink_list * list);
void dlink_add_before(void *data, dlink_node *m, dlink_node *pos, dlink_list *list);
extern void dlink_delete(dlink_node * m, dlink_list * list);
extern void dlink_move_list(dlink_list * from, dlink_list * to);
extern void dlink_move_list_tail(dlink_list * from, dlink_list * to);

dlink_node *dlink_find(void *data, dlink_list *list);
dlink_node *dlink_find_delete(void *data, dlink_list *list);
int dlink_find_destroy(void *data, dlink_list *list);

#define DLINK_FOREACH(pos, head) for (pos = (head); pos != NULL; pos = pos->next)
#define DLINK_FOREACH_SAFE(pos, n, head) for (pos = (head), n = pos ? pos->next : NULL; pos != NULL; pos = n, n = pos ? pos->next : NULL)
#define DLINK_FOREACH_PREV(pos, head) for (pos = (head); pos != NULL; pos = pos->prev)

/* Returns the list length */
#define dlink_list_length(list) (list)->length

#define dlink_add_alloc(data, list) dlink_add(data, make_dlink_node(), list)
#define dlink_add_tail_alloc(data, list) dlink_add_tail(data, make_dlink_node(), list)
#define dlink_destroy(node, list) do { dlink_delete(node, list); free_dlink_node(node); } while(0)


#endif

